#include <iostream>
#include <unistd.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <sys/shm.h>
#include "../macro.h"

using std::cout;
using std::endl;

int initSem()
{
    // 使用信号量，确保同步
    int semid = semget(1000, 1, IPC_CREAT | 0600);
    ERR_CHECK(semid, -1, "semget")
    // 设置初始值
    int ret = semctl(semid, 0, SETVAL, 1);
    ERR_CHECK(ret, -1, "semctl")

    return semid;
}

int *initShm()
{
    int shmid = shmget(1000, sizeof(int), IPC_CREAT | 0600);
    ERR_CHECK(shmid, -1, "shmget")
    int *ret = (int *)shmat(shmid, NULL, 0);
    ERR_CHECK(*ret, -1, "shmat")

    return ret;
}

void fun()
{
    constexpr static int MAX = 10000000;
    int semid = initSem();
    struct sembuf p{0, -1, SEM_UNDO}, v{0, 1, SEM_UNDO};
    int *ptr = initShm();
    if(fork()){

        for(int i{}; i < MAX; i++){
            // p: 获取锁
            semop(semid, &p, 1);
            (*ptr)++;
            // v: 释放锁
            semop(semid, &v, 1);
        }
        // 等待子进程自行结束
        wait(nullptr);
        printf("int=%d\n", *ptr);
    }else{
        for(int i{}; i < MAX; i++){
            // p: 获取锁
            semop(semid, &p, 1);
            (*ptr)++;
            // v: 释放锁
            semop(semid, &v, 1);
        }
    }
}

// 两个进程使用共享内存段，将 i 加到两千万
int main(int args, char *argv[])
{
    fun();    
    return 0;
}